/**
 * @file fifoSession.c
 * @brief Implementazione di un processo che permette di comunicare tramite le fifo.
 *
 * Tramite questo processo è possibile instaurare delle sessioni FIFO con l'applicazione principale.
 *
 * @date Apr 14, 2012
 * @author Francesco Corvino
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <interfacesock.h>

/**
 * @brief Avvia la creazione dell'applicazione principale ChatApp.
 *
 * @return -1 se la funzione non ha avuto successo, 1 altrimenti.
 */
int checkMainProcess() {
	pid_t pid;
    if ((pid = fork()) < 0) {
    	printf("Errore nel creare la nuova sessione!");
    	return -1;
    } else if (pid == 0) {      /* child */
    	execlp("./startApp", (char *)0);
    	exit(0);
    }
    return 1;
}

/**
 * @brief Si mette in attesa di un'input tra due file descriptor.
 *
 * @param fd0 Primo file descriptor.
 * @param fd1 Secondo file descriptor.
 * @return Restituisce il file descriptor da cui si attende un'input o
 * -1 se si ha un'errore o un fallimento della chiamata.
 */
int _Chat_waitInput(int fd0, int fd1){
	struct timeval tv;
	tv.tv_sec = 1000; tv.tv_usec = 0;
	fd_set fdsetread;
	FD_ZERO(&fdsetread);
	FD_SET(fd0,&fdsetread);
	FD_SET(fd1, &fdsetread);
	int maxfd = (fd0>fd1)?(fd0):(fd1);
	select(maxfd+1,&fdsetread,NULL,NULL,&tv);
	if(FD_ISSET(fd0,&fdsetread)) return 0;
	else if(FD_ISSET(fd1,&fdsetread)) return 1;
	return -1;
}

/**
 *
 * @param argc
 * @param argv
 * @return
 */
int main(int argc, char* argv[]) {
	char buffer[BUFSIZ+1];
	InterfaceSock iSock;

	/// - individua il percorso del processo principale
	char pathToDir[255];
	if(argc>2)	{
		strcpy(pathToDir,argv[1]);
	} else { // presente nella cartella locale
		strcpy(pathToDir,".");
	}

	/// - controlla se il processo principale è attivo
	if(checkMainProcess()==-1){
		puts("--- Impossibile avviare il processo principale ---");
		return -1;
	}

	/// - inizializza i file per comunicare con il processo principale
	InterfaceSock_init(&iSock,getpid(),0,SOCKSESSION_SERVER);
	if(iSock.sd==-1){
		puts("--- Errore nella creazione delle FIFO ---\n");
		return -1;
	}

	/// - comunica con il processo principale di aggiungere la sua sessione
	InterfaceSock_register(iSock.port);

	printf("--- Socket terminal on port %d ---\n",iSock.port);
	puts("--- Digitare per interagire ---\n");

	int status = 1;
	/// - avvia il loop di comunicazione
	while(status){
	    memset(buffer, 0, sizeof(buffer));
		switch(_Chat_waitInput(STDIN_FILENO,iSock.sd)){
			case 0:
				fgets(buffer, BUFSIZ, stdin);
				InterfaceSock_sendMsg(&iSock,buffer);
				puts("---------------- Messaggio inviato -----------------\n");
				break;
			case 1:
				InterfaceSock_rcvMsg(&iSock,buffer,BUFSIZ);
				printf("%s",buffer);
				break;
			default:
				printf("nessuno è pronto");
				status = 0;
				break;
		}
		if(strncmp(buffer,"end",3)==0) status = 0;

	}
	InterfaceSock_close(&iSock);
	return EXIT_SUCCESS;
}

